package com.demo.cryptology.symmetric;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Key;
import java.util.Base64;
import java.util.Random;

public class PBE {
    public static final String ALGORITHM = "PBEWITHMD5andDES";

    public static byte[] initSalt() throws Exception {
        byte[] salt = new byte[8];
        Random random = new Random();
        random.nextBytes(salt);
        return salt;
    }

    private static Key toKey(String password) throws Exception {
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKey = keyFactory.generateSecret(keySpec);
        return secretKey;
    }


    public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception {
        Key key = toKey(password);
        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 100);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
        return cipher.doFinal(data);
    }


    public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception {
        Key key = toKey(password);
        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, 100);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        String dataStr = "fasdfasd";
        System.out.println("原文:" + dataStr);
        byte[] data = dataStr.getBytes();
        String pwd = "123";
        System.out.println("密码:" + pwd);
        byte[] salt = initSalt();
        byte[] encodeData = encrypt(data, pwd, salt);
        System.out.println("加密后:" + Base64.getEncoder().encodeToString(encodeData));
        byte[] decodeData = decrypt(encodeData, pwd, salt);
        System.out.println("解密后:" + new String(decodeData));


    }
}
